package com.shangxia.lucky.lucky.job;

import com.shangxia.lucky.lucky.entity.Model;
import com.shangxia.lucky.lucky.entity.TypeList;
import com.shangxia.lucky.lucky.job.write.MatchGroupWriterThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

import static java.util.stream.Collectors.toList;

/**
 * @ProjectName: monomer
 * @ClassName: MatchGroupJob
 * @Time: 2021/9/2
 * @Author: zhouy
 * @Description:
 * @Experience:
 */

@Slf4j
@Component
public class MatchGroupJob extends MatchJob {

    @Override
    public void job() throws IOException {
        log.info("开始计算 分組任務");
        MatchGroupWriterThread matchGroupWriterThread = new MatchGroupWriterThread(configText);
        new Thread(matchGroupWriterThread).start();

        List<List<Integer>> allMatchLists = readCode(configText, configText.getBananaMatchFileName());
        Map<String, Object> params = new HashMap<>();
        List<List<Integer>> lists = readCode(configText, configText.getBananaRealCodeFileName());
        int limit = configText.getBananaMatchLimit();
        int group = 1;
        List<List<Integer>> matchLists = new ArrayList<>();
        for (int i = 0; i < allMatchLists.size(); i += limit) {
            log.info("开始计算第 {} 组", group);
            matchLists.clear();
            matchLists.addAll(allMatchLists.subList(i, Math.min(i + limit, allMatchLists.size())));
            params.put("matchLists", matchLists);
            params.put("group", group++);
            params.put("type", i);
            turnOver(params, lists, configText);
            log.info("第 {} 组计算结束", (group - 1));
        }
        log.info("所有分组计算结束");
        matchGroupWriterThread.stop();

        logOver();
    }

    @Override
    public void exportRowResult(Map<String, Object> params) {
        Integer row = (Integer) params.get("row");
        Integer maxRow = (Integer) params.get("maxRow");
        if (maxRow - row <= configText.getBananaMatchSaveSize()) {
            Integer group = (Integer) params.get("group");
            Integer type = (Integer) params.get("type");
            List<List<Integer>> matchLists = (List<List<Integer>>) params.get("matchLists");
            List<Model> resultList = ROW_MODELS.values().stream().sorted(Comparator.comparingInt(Model::getType))
                    .sorted(Comparator.comparingInt(Model::getColumn))
                    .sorted(Comparator.comparingInt(Model::getAge).reversed())
                    .limit(Math.min(ROW_MODELS.size(), configText.getBananaExportColumn())).collect(toList());
            List<TypeList> typeLists = new ArrayList<>();
            for (Model model : resultList) {
                // 分组保留最近数据
                typeLists.add(new TypeList(group, model.getColumn() + 1, model.getType() + 1, model.getAge(), matchLists.get(model.getType())));
            }
            List<List<String>> result = typeLists.stream()
                    .sorted(Comparator.comparingInt(TypeList::getGroup))
                    .sorted(Comparator.comparingInt(TypeList::getAge))
                    .sorted(Comparator.comparingInt(TypeList::getColumn))
                    .sorted(Comparator.comparingInt(TypeList::getType)).map(e -> {
                        List<String> list = new ArrayList<>();
                        list.add("" + e.getGroup());
                        list.add("" + e.getAge());
                        list.add("" + e.getColumn());
                        list.add((type + e.getType()) + "");
                        StringBuilder str = new StringBuilder();
                        for (Integer integer : e.getList()) {
                            str.append(integer).append(" ");
                        }
                        list.add(str.toString());
                        return list;
                    }).collect(toList());
            MatchGroupWriterThread.groupQueue.add(result);
        }
    }

    @Override
    public void logOver() {
        while (true) {
            if (MatchGroupWriterThread.WRITER_OVER_LOG) {
                log.info("----------------------------------------------");
                log.info("-------------------程序运行完成-----------------");
                log.info("----------------------------------------------");
                break;
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


}
